package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.ciei.dpagm.entity.*;
import com.ciei.dpagm.common.converter.JsonConverter;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import com.ciei.dpagm.common.enums.GenderEnum;
import com.ciei.dpagm.common.enums.LogTypeEnum;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.util.*;
import com.ciei.dpagm.mapper.UsersMapper;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UsersService extends BaseService<UsersMapper, Users> {
	@Autowired
	private DepartmentService departmentService;
	@Autowired
	private CompanyService companyService;
	@Autowired
	private LogService logService;
	@Autowired
	private EmailUtil emailUtil;
	@Autowired
	private FilesService filesService;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private RoleService roleService;

	public  String getUserName(Integer userId){
		Users user=findById(userId);
		if(user!=null){
			return  user.getUserName();
		}
		return "";
	}

	public void loadImage(HttpServletResponse response,String filename) throws IOException{
		String file="C:/testfile/" + filename + ".png";
		response.setContentType("image/jpg");
		File f = new File(file);
		InputStream fis = null;
		OutputStream toClient = null;
		//创建目录
		if(f.exists()==false) {
			f.mkdirs();
		}
		try {
			//String fileName = f.getName();
			response.setCharacterEncoding("utf-8");
			// 1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
			// 2.设置文件头：最后一个参数是设置下载文件名(假如我们叫a.pdf)
			response.setHeader("Content-Disposition",
					"attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
			fis = new BufferedInputStream(new FileInputStream(f));
			toClient = new BufferedOutputStream(response.getOutputStream());
			IOUtils.copy(fis, toClient);
			response.flushBuffer();
		} catch (Exception e) {
			///logger.error("exception:{}", e);
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(fis);

			IOUtils.closeQuietly(toClient);
		}
	}

	public void uploadImage(HttpServletRequest request, HttpServletResponse response,Integer userId,String itemId) throws IOException{
		// 创建一个通用的多部分解析器
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession()
				.getServletContext());
		// 判断 request 是否有文件上传,即多部分请求
		if (multipartResolver.isMultipart(request)) {
			// 转换成多部分request
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			// 取得request中的所有文件名
			Iterator<String> iter = multiRequest.getFileNames();
			while (iter.hasNext()) {
				// 取得上传文件
				MultipartFile multipartFile = multiRequest.getFile(iter.next());
				if (multipartFile != null) {

					// 取得当前上传文件的文件名称
					String fileName = multipartFile.getOriginalFilename();

					if (fileName.trim() != null && fileName.trim().length() > 0) {

						try {
							File uploadedFile = new File("c:/testfile/", userId.toString() + ".png");
							multipartFile.transferTo(uploadedFile);

						} catch (Exception e) {
							System.out.print(e.getMessage());
							e.printStackTrace();
						}

						response.setContentType("text/html; charset=utf-8");

						response.getWriter().write("{state: true, itemId: '" + itemId + "', itemValue: ''}");

					}
				}
			}
		}
	}

	public JSONObject updateUsers(Users user) {
		Json json = new Json();

		Users userObj=findById(user.getUserId());

		//无论userobj的属性为不为空，都把user中不为空的属性复制到userobj
		ClassUtil.copy(userObj, user, 1);
		updateById(userObj);

		json.setSuccess(true);
		json.setMsg("保存成功!");
		return JsonUtil.getSuccess("更新成功");
	}


	public JSONObject updatePassword(String loginName, String oldPassword, String newPassword) {
		Users user = loadByUsernameAndPassword(loginName, oldPassword);
		if (user == null) {
			return JsonUtil.getFail("原密码输入错误");
		}
		if (newPassword == null || newPassword.equals("")) {
			return JsonUtil.getFail("新密码不能为空");
		}
		user.setPassword(newPassword);
		updateById(user);
		return JsonUtil.getSuccess("密码修改成功");
	}

	/**
	 * 通过账号密码查找用户<br/>
	 * 如果查到多个用户会抛异常
	 * @param loginName 账号
	 * @param password  密码
	 * @return 用户
	 */
	public Users loadByUsernameAndPassword(String loginName, String password) {
		Map<SFunction<Users, ?>, Object> fieldValueMap = new HashMap<>();
		fieldValueMap.put(Users::getLoginName, loginName);
		fieldValueMap.put(Users::getPassword, password);
		return findOneByProperties(fieldValueMap);
	}

	public JSONObject loadUsersList() {
		List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
		List<Users> list = findAll();
		if (list != null && list.size() > 0) {
			for (Users b : list) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("value", b.getUserId());
				map.put("text", b.getUserName());
				resList.add(map);
			}
		}
		JSONObject json = new JSONObject();
		json.put("options", resList);
		return json;
	}

	/**
	 * 重置密码
	 *
	 * @param userIds
	 * @return
	 */
	public JSONObject updatePassword(String userIds) {
		if (org.apache.commons.lang3.StringUtils.isBlank(userIds)) {
			return JsonUtil.getFail("传入参数userIds为空");
		}
		String[] idArr = userIds.split(",");
		for (String id : idArr) {
			Integer iid = Integer.valueOf(id);
			Users m = findById(iid);
			if (m != null) {
				//m.setPassword(new Md5Hash(defaultPassword).toString());
				updateById(m);
			}
		}
		JSONObject json = JsonUtil.getSuccess("密码重置成功");
		return json;
	}

	public List<Users> findPage(int currentPage, int pageSize, Map<String, Object> params, String[] likeFields,
                                    String[] equalFields) {
		return findPage(currentPage, pageSize, params, likeFields, equalFields, null);
	}


	public List<Users> findPageForChoose(int currentPage, int pageSize, Map<String, Object> params, String departmentId,
                                             Integer nodeTypeId) {

		String[] equalFields;
		if (nodeTypeId != null && nodeTypeId.equals(0)) {
			equalFields = new String[] { "company.companyId", "isDelete" };
			params.put("companyId", departmentId);
			params.put("isDelete", 0);
		} else {
			equalFields = new String[] { "department.departmentId", "isDelete" };
			params.put("departmentId", departmentId);
			params.put("isDelete", 0);
		}

		return findPage(currentPage, pageSize, params, null, equalFields,null);
	}

	public int getTotalCountForChoose(Map<String, Object> params, String departmentId, Integer nodeTypeId) {

		String[] equalFields;
		if (nodeTypeId != null && nodeTypeId.equals(0)) {
			equalFields = new String[] { "company.companyId", "isDelete" };
			params.put("companyId", departmentId);
			params.put("isDelete", 0);
		} else {
			equalFields = new String[] { "department.departmentId", "isDelete" };
			params.put("departmentId", departmentId);
			params.put("isDelete", 0);
		}

		return getTotalCount(params, null, equalFields);
	}

	/**
	 * 生成用户信息导入excel模板
	 *
	 * @return
	 * @throws Exception
	 */
	public ByteArrayInputStream downLoad(Map<String, Object> params) throws Exception {
		/* 获取持久化对象 */
		List selectList = null;

		/* 生成Workbook对象 */
		Workbook workbook = this.listConvertToWookbook(selectList, params);

		/* 将Workbook对象的数据写到输出流中，再获取到输入流中并返回 */
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		workbook.write(baos);
		baos.flush();
		byte[] data = baos.toByteArray();
		return new ByteArrayInputStream(data, 0, data.length);
	}

	public Workbook listConvertToWookbook(List list, Map<String, Object> params) {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("用户信息");
		HSSFRow row = sheet.createRow(0);

		/*************** 先构造表头 ****************/
		int count = 0;

		row.createCell(count++).setCellValue(new HSSFRichTextString("登录名"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("姓名"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("部门名称"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("用户状态"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("能否创建项目"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("用户类型"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("Email"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("电话"));
		row.createCell(count++).setCellValue(new HSSFRichTextString("描述"));

		return workbook;
	}

	@SuppressWarnings("unchecked")
	public Json connectAD(String host, String post, String username, String password) {
		Json json = new Json();
		DirContext ctx = null;
		Hashtable hashEnv = new Hashtable();
		hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别(none,simple,strong)
		hashEnv.put(Context.SECURITY_PRINCIPAL, username); // AD的用户名
		hashEnv.put(Context.SECURITY_CREDENTIALS, password); // AD的密码
		hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
		hashEnv.put("com.sun.jndi.ldap.connect.timeout", "3000");// 连接超时设置为3秒
		hashEnv.put(Context.PROVIDER_URL, "ldap://" + host + ":" + post);// 默认端口389
		try {
			ctx = new InitialDirContext(hashEnv);// 初始化上下文
			json.setSuccess(true);
			json.setMsg("身份验证成功!");
		} catch (AuthenticationException e) {
			json.setMsg("身份验证失败!");
			// e.printStackTrace();
		} catch (javax.naming.CommunicationException e) {
			json.setMsg("AD域连接失败!");
			// e.printStackTrace();
		} catch (Exception e) {
			json.setMsg("身份验证未知异常!");
			e.printStackTrace();
		} finally {
			if (null != ctx) {
				try {
					ctx.close();
					ctx = null;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return json;
	}

	/**
	 * 查询用户数据
	 *
	 * @param pageParam
	 * @return
	 * @author pp
	 */
	public JSONObject loadVue(PageParam pageParam, Integer companyId) {
		JSONObject json = new JSONObject();
		JSONArray jArr = new JSONArray();
		int currentPage = pageParam.getCurrentPage();
		int pageSize = pageParam.getPageSize();
		Map<String, Object> params = pageParam.getParams();
		params.put("isDelete", 0);
		if(params.get("userName")!=null){
			params.put("loginName",params.get("userName"));

		}
		//根据当前的公司和部门数据查询对应的用户数据，如果是父部门，对应子部门的用户数据也要查询
		List<Department> allDepartment = null;
		if (params.containsKey("departmentId")) {
			Integer departmentId = (Integer) params.get("departmentId");
			if (departmentId != null) {
				Set<Integer> childrenIds = new HashSet<>();
				allDepartment = departmentService.getBaseMapper().listSameCompanyDepartments(departmentId);
				departmentService.loadChildrenDepartmentIds(allDepartment, departmentId, childrenIds);
				params.put("departmentId", new ArrayList<>(childrenIds));
			}
		}
		if (allDepartment == null) {
			allDepartment = departmentService.findByProperty("isDelete", 0);
		}
		params.put("companyId", companyId);
		QueryWrapper<Users> queryWrapper = getFormSearchWrapper(params, new String[]{"userName","loginName"},new String[]{"isDelete","companyId"},null, new String[]{"departmentId"});
        IPage<Users> page = findPageVue(currentPage, pageSize, queryWrapper);
		List<Users> baseUsersList = page.getRecords();

		if (baseUsersList.size() > 0) {
			List<Files> postAuthorizationFileList = filesService.findListByIds(baseUsersList.stream().map(Users::getPostAuthorizationId).collect(Collectors.toSet()));
			List<Files> trainingResumeFileList = filesService.findListByIds(baseUsersList.stream().map(Users::getTrainingResumeId).collect(Collectors.toSet()));
			List<Files> workLicenceFileList = filesService.findListByIds(baseUsersList.stream().map(Users::getWorkLicenceId).collect(Collectors.toSet()));
			List<Integer> userIds = baseUsersList.stream().map(Users::getUserId).collect(Collectors.toList());
			List<UserRole> userRoleList = new ArrayList<>();
			if(userIds.size()>0){
				userRoleList = userRoleService.findByUserId(userIds);
			}
			for (Users user : baseUsersList) {
				Map<String, Object> rowMap = new HashMap<>(16);
				rowMap.put("userId", user.getUserId());
				rowMap.put("userName", user.getUserName());
				rowMap.put("loginName", user.getLoginName());
				rowMap.put("jobCode", user.getJobCode());
				List<Integer> departmentIds = new ArrayList<>();
				//前端数据格式为[父节点....当前节点],当前部门节点要在最后面
				if (user.getDepartmentId() != null) {
					Department department = allDepartment.stream().filter(d -> d.getDepartmentId().equals(user.getDepartmentId()))
							.findFirst().orElse(null);
					if (department != null) {
						rowMap.put("departmentName", department.getDepartmentName());
					}
					while (department != null) {
						departmentIds.add(department.getDepartmentId());
						Integer parentId = department.getParentDepartmentId();
						department = allDepartment.stream().filter(d -> d.getDepartmentId().equals(parentId))
								.findFirst().orElse(null);
					}
					Collections.reverse(departmentIds);
					rowMap.put("department", departmentIds);
				}
				List<Integer> roleIdList = userRoleList.stream()
						.filter(u -> u.getUserId().equals(user.getUserId()))
						.map(UserRole::getRoleId)
						.collect(Collectors.toList());
				rowMap.put("roleId", roleIdList);
				rowMap.put("mobileTel", user.getMobileTel());
				rowMap.put("telephone", user.getTelephone());
				rowMap.put("email", user.getEmail());
				Optional<GenderEnum> m1 = EnumUtil.getEnumObject(GenderEnum.class, g -> g.getGenderId().equals(user.getGender()));
				rowMap.put("sex", m1.map(GenderEnum::getGender).orElse(null));
				JSONArray postAuthorizationList = new JSONArray();
				if(user.getPostAuthorizationId()!=null){
					postAuthorizationFileList.stream()
							.filter(f -> f.getFileId().equals(user.getPostAuthorizationId()))
							.findFirst()
							.ifPresent(files -> {
								Map<String, Object> map = new HashMap<>(4);
								map.put("name",files.getFileName());
								map.put("url",files.getPath());
								map.put("fileType",files.getFileType());
								map.put("fileId",files.getFileId());
								postAuthorizationList.add(map);
							});
				}
				rowMap.put("postAuthorization",postAuthorizationList);
				JSONArray trainingResumeList = new JSONArray();
				if(user.getTrainingResumeId()!=null){
					trainingResumeFileList.stream()
							.filter(f -> f.getFileId().equals(user.getTrainingResumeId()))
							.findFirst()
							.ifPresent(files -> {
								Map<String, Object> map = new HashMap<>(4);
								map.put("name",files.getFileName());
								map.put("url",files.getPath());
								map.put("fileType",files.getFileType());
								map.put("fileId",files.getFileId());
								trainingResumeList.add(map);
							});
				}
				rowMap.put("trainingResume",trainingResumeList);
				JSONArray workLicenseList = new JSONArray();
				if(user.getWorkLicenceId()!=null){
					workLicenceFileList.stream()
							.filter(f -> f.getFileId().equals(user.getWorkLicenceId()))
							.findFirst()
							.ifPresent(files -> {
								Map<String, Object> map = new HashMap<>(4);
								map.put("name",files.getFileName());
								map.put("url",files.getPath());
								map.put("fileType",files.getFileType());
								map.put("fileId",files.getFileId());
								workLicenseList.add(map);
							});
				}
				rowMap.put("workLicense",workLicenseList);
				jArr.add(rowMap);
			}
		}
		json.put(APP.DATA, jArr);
		json.put(APP.TOTAL_COUNT, page.getTotal());
		json.put(APP.POS, (currentPage - 1) * pageSize);
		json.put(APP.CURRENT_PAGE, page.getCurrent());
		return json;
	}

	/**
	 * 删除单个用户
	 * @param requestJson {"userId":123}
	 * @return
	 */
	@Transactional
	public JSONObject delete(JSONObject requestJson) {
		Integer userId = requestJson.getInteger("userId");
		if (userId == null) {
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "userId不能为空");
		}
		boolean success = removeById(userId);
		if (success) {
			userRoleService.delete(userId);
			return JsonUtil.getSuccess("删除成功!");
		}else {
			return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_FAIL, "删除失败");
		}
	}

	public JSONObject addOrUpdateUsers(JSONObject jsonObject, String type, Users user) {
		JSONObject json = null;
		String[] propertyNames = {"loginName","isDelete"};
		String[] values = {jsonObject.getString("loginName"),"0"};
		//List<Users> usersList=findByPropertiesNotSelf(propertyNames, values,jsonObject.getString("loginName"));
		List<Users> baseUsersList =new ArrayList<>();
		if("add".equals(type)){
			baseUsersList =findByProperties(propertyNames, values);
			if(baseUsersList.size()>0){
				json = JsonUtil.getFail("登陆账户已存在,添加失败！");
			}
		}else{
			baseUsersList =findByPropertiesNotSelf(propertyNames, values,jsonObject.getInteger("userId"));
			if(baseUsersList.size()>0){
				json = JsonUtil.getFail("登陆账号已存在,更新失败！");
			}
		}
		if(baseUsersList.size()==0 ) {
			JsonConverter<Users> jsonConverter=new JsonConverter<>();
			Users addOrUpdateBaseUsers;
			if(jsonObject.getInteger("userId")!=null){
				addOrUpdateBaseUsers = findById(jsonObject.getInteger("userId"));
			}else{
				addOrUpdateBaseUsers = new Users();
			}
			addOrUpdateBaseUsers = jsonConverter.convert(jsonObject, addOrUpdateBaseUsers);
			String sex = jsonObject.getString("sex");
			Optional<GenderEnum> m1 = EnumUtil.getEnumObject(GenderEnum.class, g -> g.getGender().equals(sex));
			addOrUpdateBaseUsers.setGender(m1.isPresent() ? m1.get().getGenderId() : null);
			//前端数据格式为[父节点....当前节点],当前部门节点在最后面，只需要当前部门节点
			if(jsonObject.getJSONArray("department")!=null){
				if(jsonObject.getJSONArray("department").size()>0){
					JSONArray departmentIds = jsonObject.getJSONArray("department");
					addOrUpdateBaseUsers.setDepartmentId(departmentIds.getInteger(departmentIds.size()-1));
				}
			}

			List<Files> filesList = new ArrayList<>();
			//前端传的文件为一个数组，键为code，每一个文件都有不同的code
			// 所以将全部的code都做一次非空判断，有数据的就返回该文件数据，无数据就返回null
			Files postAuthorization = propAdd("postAuthorization", jsonObject, user);
			Files trainingResume = propAdd("trainingResume", jsonObject, user);
			Files workLicense = propAdd("workLicense", jsonObject, user);
			if(postAuthorization!=null){
				filesList.add(postAuthorization);
			}
			if(trainingResume!=null){
				filesList.add(trainingResume);
			}
			if(workLicense!=null){
				filesList.add(workLicense);
			}
			addOrUpdateBaseUsers.setCompanyId(user.getCompanyId());
			addOrUpdateBaseUsers.setCreateTime(DateUtil.getTimestamp(new Date()));
			if("add".equals(type)){
				//当添加用户的时候随机生成密码，更新不用
				addOrUpdateBaseUsers.setPassword(jsonObject.getString("password"));
				filesService.insertBatchSomeColumn(filesList);
				if(postAuthorization!=null){
					addOrUpdateBaseUsers.setPostAuthorizationId(postAuthorization.getFileId());
				}
				if(trainingResume!=null){
					addOrUpdateBaseUsers.setTrainingResumeId(trainingResume.getFileId());
				}
				if(workLicense!=null){
					addOrUpdateBaseUsers.setWorkLicenceId(workLicense.getFileId());
				}
				addOrUpdateBaseUsers.setCompanyId(user.getCompanyId());
				save(addOrUpdateBaseUsers);
				json = JsonUtil.getSuccess("添加成功");
				json.put("id", addOrUpdateBaseUsers.getUserId());
			}else{
				List<Files> savaFiles = new ArrayList<>();
				for(Files files :filesList){
					if(files.getFileId()==null){
						savaFiles.add(files);
						filesService.removeFile(files.getRelationTypeId(),files.getRelationId());
					}
				}
				if(savaFiles.size()>0){
					filesService.insertBatchSomeColumn(savaFiles);
				}
				//解决字段不能为空
				LambdaUpdateWrapper<Users> wrapper = new LambdaUpdateWrapper<>();
				if(postAuthorization!=null){
					addOrUpdateBaseUsers.setPostAuthorizationId(postAuthorization.getFileId());
				}else{
					if(addOrUpdateBaseUsers.getPostAuthorizationId()!=null){
						filesService.removeById(addOrUpdateBaseUsers.getPostAuthorizationId());
						wrapper.set(Users::getPostAuthorizationId,null);
					}
				}
				if(trainingResume!=null){
					addOrUpdateBaseUsers.setTrainingResumeId(trainingResume.getFileId());
				}else{
					if(addOrUpdateBaseUsers.getTrainingResumeId()!=null){
						filesService.removeById(addOrUpdateBaseUsers.getTrainingResumeId());
						wrapper.set(Users::getTrainingResumeId,null);
					}
				}
				if(workLicense!=null){
					addOrUpdateBaseUsers.setWorkLicenceId(workLicense.getFileId());
				}else {
					if(addOrUpdateBaseUsers.getWorkLicenceId()!=null){
						filesService.removeById(addOrUpdateBaseUsers.getWorkLicenceId());
						wrapper.set(Users::getWorkLicenceId,null);
					}
				}
				wrapper.eq(Users::getUserId, addOrUpdateBaseUsers.getUserId());
				update(addOrUpdateBaseUsers,wrapper);
				json = JsonUtil.getSuccess("更新成功");
			}
		}
		return json;
	}

	/**
	 * 前端传入不同类型的文件都用不同的键来代替，返回处理好的文件数据
	 */
	public Files propAdd(String prop, JSONObject jsonObject, Users user){
		Files files = null;
		if(jsonObject.getJSONArray(prop)!=null){
			JSONArray list = jsonObject.getJSONArray(prop);
			if(list.size()>0){
				for(int i =0;i<list.size();i++){
					files = new Files();
					JSONObject fileData = list.getJSONObject(i);
					if(fileData.getString("relationId")!=null){
						files.setRelationId(Integer.valueOf(fileData.getString("relationId")));
					}
					if(fileData.getString("relationTypeId")!=null){
						files.setRelationTypeId(Integer.valueOf(fileData.getString("relationTypeId")));
					}
					if(!"".equals(fileData.getString("fileType"))){
						files.setFileType(fileData.getString("fileType"));
					}
					files.setUploadTime(DateUtil.getTimestamp(new Date()));
					files.setUploadUserId(user.getUserId());
					if(!"".equals(fileData.getString("url"))){
						files.setPath(fileData.getString("url"));
					}
					if(!"".equals(fileData.getString("name"))){
						files.setFileName(fileData.getString("name"));
					}
					if(fileData.getInteger("fileId")!=null){
						files.setFileId(fileData.getInteger("fileId"));
					}
				}
			}
		}
		return files;
	}

	/**
	 * 多条件等值查询并且忽略自己
	 *
	 * @param propertyNames 属性名数组
	 * @param values        属性值数组
	 * @return 满足条件的所有记录
	 */
	public List<Users> findByPropertiesNotSelf(String[] propertyNames, Object[] values, Integer userId) {

		QueryWrapper<Users> wrapper = new QueryWrapper<>();
		propertyNames = ConvertUtil.humpToLines(propertyNames);
		if (propertyNames != null) {
			for (int i = 0; i < propertyNames.length; i++) {
				if (values[i] != null) {
					wrapper.eq(propertyNames[i], values[i]);
				} else {
					wrapper.isNull(propertyNames[i]);
				}
			}
		}
		if(userId!=null){
			wrapper.notIn("user_id",userId);
		}
		return list(wrapper);
	}

	/**
	 * 重置密码
	 * @param userId	用户ID
	 * @return			新密码
	 */
	public String resetVue(Integer userId, Users currentUser, String type, String stringRandom) {
		Users user = findById(userId);
		String originPassword = user.getPassword();
		switch (type){
			case "send":
				user.setPassword(DigestUtils.md5DigestAsHex(stringRandom.getBytes()));
				break;
			case "get":
				user.setPassword(stringRandom);
				break;
			default:
				break;
		}
		user.setPswordChangeTime(new Timestamp(System.currentTimeMillis()));
		updateById(user);
		logService.addLog(LogTypeEnum.MANAGE_USER, "重置用户密码", null, user.getLoginName() + ":" + originPassword, user.getLoginName() + ":" + stringRandom, currentUser);
		return stringRandom;

	}

	/**
	 * 重置密码
	 * @param data
	 * @param currentUser
	 **/
	public JSONObject resetPassword(JSONObject data, Users currentUser) {
		if (data.getInteger("userId") == null) {
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "userId不能为空,重置密码失败!");
		}
		Integer userId = data.getInteger("userId");
		Users user = findById(userId);
		user.setPassword(data.getString("password"));
		user.setPswordChangeTime(new Timestamp(System.currentTimeMillis()));
		updateById(user);
		logService.addLog(LogTypeEnum.MANAGE_USER, "重置用户密码", null, user.getLoginName(), user.getLoginName(), currentUser);

		JSONObject responseJson = new JSONObject();
		responseJson.fluentPut("loginName", user.getLoginName())
				.fluentPut("password", user.getPassword());
		return JsonUtil.getSuccess("重置密码成功").fluentPut("data", responseJson);
	}

	public JSONObject sendVue(JSONObject jsonObject, Users sendUser) {
		List<String> contactEmails = new ArrayList<>();
		String title = companyService.getCompanyName(sendUser.getCompanyId());
		JSONObject json = new JSONObject();
		if(jsonObject.getInteger("userId")!=null){
			//收件人
			String result=resetVue(jsonObject.getInteger("userId"), sendUser,"send",getStringRandom(8));
			Integer userId=jsonObject.getInteger("userId");
			Users user = findById(userId);
			String content = "您好,你当前的登陆账户为:"+user.getLoginName()+",密码为:"+result;
			contactEmails.add(user.getEmail());
			emailUtil.send(contactEmails,title,content,null);
			json = JsonUtil.getSuccess("发送成功");
		}else{
			json = JsonUtil.getFail("userId不能为空,发送邮件失败!");
		}

		return json;
	}

	//生成随机数字和字母,
	public String getStringRandom(int length) {
		StringBuffer val = new StringBuffer();
		Random random = new Random();
		//参数length，表示生成几位随机数
		for(int i = 0; i < length; i++) {
			String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
			//输出字母还是数字
			if( "char".equalsIgnoreCase(charOrNum) ) {
				//输出是大写字母还是小写字母
				int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
				val.append((char)(random.nextInt(26) + temp));
			} else if( "num".equalsIgnoreCase(charOrNum) ) {
				val.append(String.valueOf(random.nextInt(10)));
			}
		}
		return val.toString();
	}

	/**
	 * 修改密码
	 * @param oldPassword	旧密码
	 * @param newPassword	新密码
	 * @param user			被修改的用户
	 * @return
	 */
	public JSONObject changePassword(String oldPassword, String newPassword, Users user) {
		Users userToChange = findById(user.getUserId());
		if (userToChange == null ) {
			return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY, "找不到对应的用户");
		}
		if(!userToChange.getPassword().equals(oldPassword)){
			return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY, "旧密码不正确");
		}
		Users updateUser = new Users();
		updateUser.setUserId(userToChange.getUserId());
		updateUser.setPassword(newPassword);
		updateById(updateUser);
		logService.addLog(LogTypeEnum.MANAGE_USER,"修改密码","系统管理",null,null);

		return JsonUtil.getSuccess("");
	}

	/**
	 * 获取所有值班人员
	 * @return
	 */
	public JSONObject getAllOperatorOnDuty() {
		JSONArray jsonArray = new JSONArray();
		List<UserRole> userRoleList = userRoleService.findByProperty("roleId", 1001);
		if (!userRoleList.isEmpty()) {
			List<Users> baseUsersList = findListByIds(userRoleList.stream().map(UserRole::getUserId).collect(Collectors.toSet()));
			if (!baseUsersList.isEmpty()) {
				List<Department> departmentList = departmentService.findListByIds(baseUsersList.stream().map(Users::getDepartmentId).collect(Collectors.toSet()));
				for (Users baseUsers : baseUsersList) {
					JSONObject data = new JSONObject();
					data.fluentPut("userId", baseUsers.getUserId())
							.fluentPut("loginName", baseUsers.getLoginName())
							.fluentPut("userName", baseUsers.getUserName());
					Department department = departmentList.stream().filter(d -> d.getDepartmentId().equals(baseUsers.getDepartmentId())).findFirst().orElse(null);
					data.put("departmentName", department == null ? "" : department.getDepartmentName());

					jsonArray.add(data);
				}
			}
		}

		return JsonUtil.getSuccess("").fluentPut(APP.DATA, jsonArray);
	}

	/**
	 * 根据用户名称获取用户列表
	 * @param userName
	 * @return
	 */
	public JSONObject getUserListByUserName(String userName){
		LambdaQueryWrapper<Users> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.like(Users::getUserName,userName);
		List<Users> baseUsersList = list(lambdaQueryWrapper);
		List<JSONObject> userDataList = new ArrayList<>();
		for(Users baseUsers : baseUsersList){
			JSONObject data = new JSONObject();
			if(baseUsers.getUserName() == null){
				continue;
			}
			if(baseUsers.getUserName().trim().isEmpty()){
				continue;
			}
			data.put("userId", baseUsers.getUserId());
			data.put("value", baseUsers.getUserName());
			if(baseUsers.getMobileTel() == null){
				data.put("phone", baseUsers.getTelephone() == null ? "" : baseUsers.getTelephone());
			}else{
				data.put("phone", baseUsers.getMobileTel());
			}
			userDataList.add(data);
		}
		return JsonUtil.getSuccess("").fluentPut(APP.DATA,userDataList);
	}

	/**
	 * 获取用户拥有的角色ID
	 * @param userId 用户ID
	 * @return
	 */
	public JSONObject getRoleIdsByUserId(Integer userId) {
		if (userId == null) {
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "userId不能为空");
		}
		Set<Integer> roleIdSet = userRoleService.getRoleIdSet(userId);
		return JsonUtil.getSuccess("查询成功").fluentPut(APP.DATA, roleIdSet);
	}

	/**
	 * 批量分配角色
	 *
	 * @param configJson 配置数据
	 * @return
	 */
	public JSONObject setUserRoles(JSONObject configJson) {
		Integer userId = configJson.getInteger("userId");
		if (userId == null) {
			return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, "userId不能为空");
		}
		boolean success;
		JSONArray roleIdArray = configJson.getJSONArray("roleIds");
		if (roleIdArray == null || roleIdArray.isEmpty()) {
			success = userRoleService.saveOrUpdate(userId, null);
		} else {
			success = userRoleService.saveOrUpdate(userId, roleIdArray.toJavaList(Integer.class));
		}
		if (success) {
			return JsonUtil.getSuccess("设置成功");
		} else {
			return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_FAIL, "设置失败");
		}
	}

	/**
	 * 是否系统管理员用户
	 * @param userId 用户ID
	 * @return true 表示是系统管理员用户
	 */
	public boolean isAdminUser(Integer userId) {
		return Users.ADMIN_USER_ID.equals(userId);
	}

	/**
	 * 是否系统管理员用户
	 * @param userId 用户ID
	 * @return true 表示是系统管理员用户
	 */
	public boolean isAdmin(Integer userId) {
		return isAdminUser(userId) || roleService.isAdminRoleByUserId(userId);
	}

	/**
	 * 根据身份证号查询用户
	 * @param idCard 身份证号
	 * @return
	 */
	public Users getByIdCard(String idCard){
		LambdaQueryWrapper<Users> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(Users::getUserIdCard,idCard);
		List<Users> usersList = list(lambdaQueryWrapper);
		if(usersList.isEmpty()){
			return null;
		}else{
			return usersList.get(0);
		}
	}

	/**
	 * 添加用户
	 * @param userId
	 */
	public Users addUser(String userId,String userName,Integer roleId){
		Users users = new Users();
		users.setUserName(userName);
		users.setLoginName(userId);
		users.setPassword("");
		save(users);
		userRoleService.saveOrUpdate(users.getUserId(),Arrays.asList(roleId));
		return users;
	}

}